/**
 * 路由守卫配置
 */
import type { Router, RouteRecordRaw, RouteLocationNormalized } from 'vue-router';
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
import { AxiosCanceler } from '/@/common/util/axiosCancel';
import { Modal, notification } from 'ant-design-vue';
import { warn } from '/@/utils/log';
import { unref } from 'vue';
import { setRouteChange, removeTabChangeListener } from '/@/router/support/routeHelper';
import nProgress from 'nprogress';
import projectSetting from '/@/settings/projectSetting';

import { useAppStoreWithOut, useAppStore } from '/@/store/modules/app';
import { useUserStoreWithOut } from '/@/store/modules/user';
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
import { useUserStore } from '/@/store/modules/user';
import { usePermissionStore } from '/@/store/modules/permission';
import { PageEnum, PageConstantEnum } from '/@/common/enums/sysEnum';

// Don't change the order of creation
export function setupRouterGuard(router: Router) {
  createPageGuard(router);
  createPageLoadingGuard(router); //加载进度条
  createHttpGuard(router);        //切换路由，取消未完成的请求
  createScrollGuard(router);      //切换路由，回到顶部
  createMessageGuard(router);     //切换路由，关闭弹框和消息
  createProgressGuard(router);    //进度条配置
  createMenuGuard(router);        //菜单路由配置
  createStateGuard(router);    //重新登录清空打开的tab
}

/**
 * 一打开的页面tab，关闭之后，则活动（active）的tab不展示
 * Hooks for handling page state
 */
function createPageGuard(router: Router) {
  const loadedPageMap = new Map<string, boolean>();
  router.beforeEach(async (to) => {
    // 获取缓存，减少性能损失
    to.meta.loaded = !!loadedPageMap.get(to.path);
    // Notify routing changes
    setRouteChange(to);
    return true;
  });
  router.afterEach((to) => {
    loadedPageMap.set(to.path, true);
  });
}

/**
 * 加载进度条
 */
function createPageLoadingGuard(router: Router) {
  const userStore = useUserStoreWithOut();
  const appStore = useAppStoreWithOut();
  const { getOpenPageLoading } = useTransitionSetting();
  router.beforeEach(async (to) => {
    if (!userStore.getToken) {
      return true;
    }
    if (to.meta.loaded) {
      return true;
    }
    if (unref(getOpenPageLoading)) {
      appStore.setPageLoadingAction(true);
      return true;
    }
    return true;
  });
  router.afterEach(async () => {
    if (unref(getOpenPageLoading)) {
      // TODO Looking for a better way
      // The timer simulates the loading time to prevent flashing too fast,
      setTimeout(() => {
        appStore.setPageLoading(false);
      }, 220);
    }
    return true;
  });
}

/**
 * 切换路由，取消未完成的请求
 * @param router
 */
function createHttpGuard(router: Router) {
  const { removeAllHttpPending } = projectSetting;
  let axiosCanceler: Nullable<AxiosCanceler>;
  if (removeAllHttpPending) {
    axiosCanceler = new AxiosCanceler();
  }
  router.beforeEach(async () => {
    // Switching the route will delete the previous request
    axiosCanceler?.removeAllPending();
    return true;
  });
}

/**
 * 切换路由，回到顶部
 * @param router
 */
function createScrollGuard(router: Router) {
  const isHash = (href: string) => {
    return /^#/.test(href);
  };
  const body = document.body;
  router.afterEach(async (to) => {
    // scroll top
    isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0);
    return true;
  });
}

/**
 * 切换路由时，关闭消息实例
 * @param router
 */
function createMessageGuard(router: Router) {
  const { closeMessageOnSwitch } = projectSetting;
  router.beforeEach(async () => {
    try {
      if (closeMessageOnSwitch) {
        Modal.destroyAll();
        notification.destroy();
      }
    } catch (error) {
      warn('message guard error:' + error);
    }
    return true;
  });
}

//进度条配置
function createProgressGuard(router: Router) {
  const { getOpenNProgress } = useTransitionSetting();
  router.beforeEach(async (to) => {
    if (to.meta.loaded) {
      return true;
    }
    unref(getOpenNProgress) && nProgress.start();
    return true;
  });
  router.afterEach(async () => {
    unref(getOpenNProgress) && nProgress.done();
    return true;
  });
}

//状态守卫：进入登录页清空所有状态
function createStateGuard(router: Router) {
  router.afterEach((to) => {
    // 进入登录页面并清除认证信息
    if (to.path === PageEnum.BASE_LOGIN) {
      const tabStore = useMultipleTabStore();
      const userStore = useUserStore();
      const appStore = useAppStore();
      const permissionStore = usePermissionStore();
      appStore.resetAllState();
      permissionStore.resetState();
      tabStore.resetState();
      userStore.resetState();
      removeTabChangeListener();
    }
  });
}

/**
 * 菜单路由配置
 * @param router 
 */
function createMenuGuard(router: Router) {
  const userStore = useUserStoreWithOut();
  const permissionStore = usePermissionStore();
  const whitePathList: string[] = [PageEnum.BASE_LOGIN, PageEnum.OAUTH2_LOGIN_PAGE_PATH, PageEnum.TOKEN_LOGIN];
  // 自定义首页跳转次数
  let homePathJumpCount = 0;
  router.beforeEach(async (to, from, next) => {
    // debugger
    //默认首页配置
    if (homePathJumpCount < 1 && from.path === PageEnum.BASE_LOGIN && userStore.getUserInfo.homePath) {
      homePathJumpCount++;
      next(userStore.getUserInfo.homePath);
      return;
    }
    //登录页跳过
    if (whitePathList.includes(to.path)) {
      next();
      return;
    }
    if ( permissionStore.getIsDynamicAddedRoute) {
      next();
      return;
    }
    // 构建后台菜单路由
    const routes = await permissionStore.buildMenu();
    routes.forEach((route) => {
      router.addRoute(route as unknown as RouteRecordRaw);
    });
    permissionStore.setDynamicAddedRoute(true);
    next({ path: to.fullPath, replace: true, query: to.query });
  });
}